package com.telnetnz.ticketdesk.bean;

import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.springframework.beans.BeanUtils;

import com.rockbb.common.utilities.ObjectUtils;
import com.telnetnz.ticketdesk.bean.misc.ComparableObject;
import com.telnetnz.ticketdesk.bean.misc.OperationLogObject;
import com.telnetnz.ticketdesk.dao.entity.TicketEntity;
import com.telnetnz.ticketdesk.service.AttachmentService;
import com.telnetnz.ticketdesk.service.OperationLogService;
import com.telnetnz.ticketdesk.service.ProjectService;
import com.telnetnz.ticketdesk.service.ProjectToUserService;
import com.telnetnz.ticketdesk.service.TicketCommentService;
import com.telnetnz.ticketdesk.service.TicketService;
import com.telnetnz.ticketdesk.service.TicketToTagService;
import com.telnetnz.ticketdesk.service.TicketToUserService;
import com.telnetnz.ticketdesk.service.UserService;

public class Ticket extends TicketEntity implements OperationLogObject,
		ComparableObject {

	private static final long serialVersionUID = -7161151140740193930L;

	public List<Attachment> getAttachments()
	{
		return AttachmentService.getAttachmentsByPageAndCondition(
				0, 
				10, 
				AttachmentService.ORDERBY_CREATE_TIME, 
				0, 
				getId(), 
				0L,
				0L);
	}

	public List<Tag> getTags()
	{
		return TicketToTagService.getTagsByTicketId(getId());
	}

	public List<TicketToUser> getUsers()
	{
		return TicketToUserService.getByTicketId(getId());
	}

	public List<OperationLog> getOperationLogs()
	{
		return OperationLogService.getLogsByPageAndCondition(
				0, 
				10, 
				OperationLogService.ORDERBY_TIME, 
				0, 
				0L, 		// userId
				OperationLogService.OBJECT_TYPE_TICKET, // objectType
				getId(), 
				null, 
				null, 
				null);
	}

	public static Ticket adapt(TicketEntity entity) {
		if (entity == null)
			return null;
		Ticket bean = new Ticket();
		BeanUtils.copyProperties(entity, bean);
		return bean;
	}

	public TicketEntity toEntity() {
		return this;
	}

	/**
	 * Return true in any of the following cases: 
	 * - This user is the creator,
	 * - This user is in the project to which this ticket belongs 
	 * - This user was involved in this ticket
	 * 
	 * @param userId
	 * @return
	 */
	public boolean isViewable(long userId)
	{ 
		if (getCreatorId() == userId) return true;

		ProjectToUser projectToUser = ProjectToUserService.getProjectToUser(getProjectId(), userId);
		if (projectToUser != null) return true;

		TicketToUser ticketToUser = TicketToUserService.getTicketToUser(getId(), userId);
		if (ticketToUser != null) return true;

		return false;
	}

	/**
	 * Get the boolean whether this ticket is editable for specific user
	 * - If this is a new ticket that hasn't been stored, true
	 * - If user is the creator and the ticket hasn't been assigned, true
	 * - If user not in this project, false
	 * - If user in this project, and his role is manager, true
	 * - Other situations, false
	 * 
	 * @param userId
	 * @return
	 */
	public boolean isEditable(long userId)
	{
		if (getId() == 0) return true;
		if (getOwnerId() == 0 && getCreatorId() == userId) return true;

		ProjectToUser projectToUser = ProjectToUserService.getProjectToUser(getProjectId(), userId);
		return (projectToUser == null)? false : (
				(projectToUser.getRole() == ProjectToUserService.ROLE_MANAGER)? true : false);
	}

	public Project getProject() {
		return ProjectService.getProject(getProjectId());
	}

	public User getOwner() {
		return UserService.getUser(getOwnerId());
	}

	public User getCreator() {
		return UserService.getUser(getCreatorId());
	}

	public User getUpdater() {
		return UserService.getUser(getUpdaterId());
	}

	public List<TicketComment> getComments() {
		return TicketCommentService.getByPageAndCondition(
				0, 
				20, 
				TicketCommentService.ORDERBY_CREATETIME, 
				1, 
				getId(), 
				0, 
				0);
	}

	public Map<String, List<String>> compare() {
		Ticket a = TicketService.getRawTicket(getId());
		return ObjectUtils.compare(a.toEntity(), this.toEntity(), TicketEntity.class);
	}

	public String getObjectName() {
		return this.getSubject();
	}

	public String getObjectSummary() {
		return Jsoup.parse(getContent()).text().substring(0, 200);
	}
}